package com.tdrc.article.controller;

import com.rabbitmq.client.Channel;
import com.tdrc.article.service.ArticleService;
import com.tdrc.common.beans.ResultCode;
import com.tdrc.common.core.rabbitmq.RabbitExChangeConfig;
import com.tdrc.common.util.JsonResult;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.Callable;

/**
 * @author dpf
 * @version 1.0
 * @date 2020-6-10 11:11
 * @instruction ...
 */
@RestController
@RequestMapping("/article")
public class ArticleController {
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private ArticleService articleService;

    private Logger log = LogManager.getLogger(ArticleController.class);;
    @GetMapping("/list")
    public Object list(){
        return new JsonResult(ResultCode.OK,articleService.listArticle());
    }

    @GetMapping("/test")
    public Object test(){
        try {
            Thread.sleep(60000);
            return new JsonResult(ResultCode.OK);
        } catch (InterruptedException e) {
            e.printStackTrace();
            return new JsonResult(ResultCode.ERROR);
        }

    }

    @GetMapping("/test2")
    public Callable<String> getFoobar()  {
        return new Callable<String>() {
            @Override
            public String call()   {
                try {
                    Thread.sleep(20000);
                    return "success";
                } catch (InterruptedException e) {
                  //  e.printStackTrace();
                    return "time-out";
                }
            }
        };
    }
    @GetMapping("/sendSms")
    private void sendSms() throws InterruptedException {
        String msg = "HelloWorld rabbitmq";
        for(Integer i=0;i<10;i++){
            CorrelationData correlationData = new CorrelationData(i.toString());
            rabbitTemplate.convertAndSend(RabbitExChangeConfig.DESTINATION_NAME, RabbitExChangeConfig.SMS_ROUTING_KEY, msg+i ,correlationData);
        }

    }
    // @RabbitListener(queues = RabbitExChangeConfig.SMS_QUEUE, containerFactory = "simpleRabbitListenerContainerFactory")
    public void sms_msg(Message message, Channel channel, @Headers Map<String, Object> headers) throws IOException {
        long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
        try {

                System.out.println("sms_msg消费者收到消息 : " + new String(message.getBody(), "UTF-8"));
                /**
                 * 手动ack
                 * deliveryTag:该消息的index
                 * multiple：是否批量.true:将一次性ack所有小于deliveryTag的消息。
                 */
                channel.basicAck(deliveryTag, false);
        } catch (Exception e) {
            //消息退回 (可以在可视化界面看到)
            //批量退回 退回之后重回消息队列 true  false的话就是丢弃这条信息，如果配置了死信队列，那这条消息会进入死信队列
            channel.basicNack(deliveryTag, false, true);
            //单条退回 channel.basicReject();
        }
    }
   // @RabbitListener(queues = RabbitExChangeConfig.DEAD_LETTER_QUEUE, containerFactory = "simpleRabbitListenerContainerFactory")
    public void reciveDeadLetter(Message message, Channel channel, @Headers Map<String, Object> headers) throws IOException {
        long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
        try {

            System.out.println("死信队列消费者收到消息 : " + new String(message.getBody(), "UTF-8"));
            /**
             * 手动ack
             * deliveryTag:该消息的index
             * multiple：是否批量.true:将一次性ack所有小于deliveryTag的消息。
             */
            channel.basicAck(deliveryTag, false);
        } catch (Exception e) {
            //消息退回 (可以在可视化界面看到)
            //批量退回 退回之后重回消息队列 true  false的话就是丢弃这条信息，如果配置了死信队列，那这条消息会进入死信队列
            channel.basicNack(deliveryTag, false, true);
            //单条退回 channel.basicReject();
        }
    }
}
